package com.xiyuan.smartutils.template.engine.statement;

import com.xiyuan.smartutils.Validates;
import com.xiyuan.smartutils.template.engine.StatementParser;
import com.xiyuan.smartutils.template.engine.TagType;
import com.xiyuan.smartutils.template.engine.VariableMap;
import com.xiyuan.smartutils.template.engine.exception.StatementException;

import java.io.PrintWriter;

public final class _RETURN extends Statement
{
    private static final long serialVersionUID = 1L;
    
    /** 用户控制函数返回 */
    public static final class ReturnException extends RuntimeException
    {
        private static final long serialVersionUID = 1L;
        private Object value = null;
        
        ReturnException()
        {
        }
        
        ReturnException(Object returnValue)
        {
            this.value = returnValue;
        }
        
        public Object getValue()
        {
            return value;
        }
    }
    
    public _RETURN(StatementParser parser)
    {
        super(parser);
    }
    
    @Override
    protected void build(VariableMap variableMap, PrintWriter out)
    {
        if (expressions.isEmpty())
            throw new ReturnException();// 无返回值
        else
            throw new ReturnException(expressions.get(0).execute(variableMap));// 有返回值
    }
    
    @Override
    public TagType getType()
    {
        return TagType.RETURN;
    }
    
    @Override
    public boolean parseTag(StatementParser parser) throws StatementException
    {
        StringBuilder value = new StringBuilder();
        char ch = 0, quote = 0, prvChar = 0;
        int expression_begin_line = this.getLineNo(), expression_begin_column = this.getBeginColumn();
        boolean space = false;
        while (parser.hasNext())
        {
            prvChar = value.length() == 0 ? 0 : ch;
            ch = parser.next();
            if (value.length() == 0 && Validates.isWhitespace(ch))
            {
                space = true;
                continue;
            }
            
            value.append(ch);
            if (value.length() == 1)
            {
                expression_begin_line = parser.getLineNum();
                expression_begin_column = parser.getColumn();
            }
            
            if (quote == 0 && (ch == _QUOTE_ || ch == _DOUBLE_QUOTE_))
            {
                quote = ch;
                continue;
            }
            
            // 字符串结束
            if (quote != 0 && prvChar != _BACK_SLASH_ && ch == quote)
            {
                quote = 0;
                continue;
            }
            
            // 判断标签是否结束 ,当前标签为‘>’视为结束
            int endTagIndex = ch == _GATHER_ ? value.length() - 1 : -1;
            if (endTagIndex > 0 && value.charAt(endTagIndex - 1) == _SLASH_)
                endTagIndex--;// 如果是 ‘/>’ 结束则需要重置 结束索引 为‘/’对应的索引
            else
                endTagIndex = -1;
            if (quote == 0 && endTagIndex != -1)
            {//
                this.setCompleteTag();
                if (endTagIndex != 0)
                {
                    if (!space)
                        return false;
                    // 只是以#return开头而已
                    value.setLength(endTagIndex);
                    // 解析表达式
                    this.parseExpression(expression_begin_line, expression_begin_column, value);
                }
                
                break;
            }
            
        }
        
        if (!this.isCompleteTag())
            throw new StatementException(this.getPath(), this.getLineNo(), this.getBeginColumn(), "文档已结束。" + getType() + "标签未找到结束符‘/>’");
        
        this.setStatement(this.getStatement() + (expressions.isEmpty() ? "" : (" " + expressions.get(0))) + getType().getTagComplete());
        return true;
    }
    
}
